import { resolve } from 'path'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import styleImport from 'vite-plugin-style-import'
import legacy from '@vitejs/plugin-legacy'
import eslintPlugin from './build/vite-eslint'

function pathResolve(dir) {
  return resolve(__dirname, '.', dir)
}

// https://vitejs.dev/config/
export default defineConfig(async ({ command, mode }) => {
  const defaultConfig = {
    base: '/',
    publicDir: 'public',
    build: {
      outDir: 'dist',
      cssCodeSplit: true,
      target: 'es2015',
      assetsDir: 'assets',
      assetsInlineLimit: 0,
      sourcemap: false,
      rollupOptions: {},
      /**
       * Type: boolean | 'terser' | 'esbuild'
       * Default: 'terser'
       *
       * Set to false to disable minification,
       * or specify the minifier to use.
       * The default is Terser which is slower but produces smaller bundles in most cases.
       * Esbuild minification is significantly faster, but will result in slightly larger bundles.
       */
      minify: 'terser',
      terserOptions: {},
      cleanCssOptions: {},
      /**
       * Enable/disable brotli-compressed size reporting.
       * Compressing large output files can be slow,
       * so disabling this may increase build performance for large projects.
       */
      brotliSize: false,
      /**
       * Type: number
       * Default: 500
       * Limit for chunk size warnings (in kbs).
       */
      chunkSizeWarningLimit: 200,
      watch: null,
    },
    resolve: {
      /**
       * Will be passed to @rollup/plugin-alias as its entries option.
       * Can either be an object, or an array of { find, replacement } pairs.
       */
      alias: {
        '@': pathResolve('src'),
      },
      /**
       * If you have duplicated copies of the same dependency in your app
       * (likely due to hoisting or linked packages in monorepos),
       * use this option to force Vite to always resolve listed dependencies
       * to the same copy (from project root).
       */
      dedupe: [],
      extensions: [
        // '.mjs',
        '.js',
        // '.ts',
        // '.jsx',
        // '.tsx',
        // '.json',
      ],
    },
    css: {
      preprocessorOptions: {
        scss: {
          // additionalData: `$injectedColor: orange;`
        },
      },
    },
    json: {
      /**
       * Whether to support named imports from .json files.
       */
      namedExports: true,
      /**
       * If set to true, imported JSON will be transformed into export default JSON.parse("...")
       * which is significantly more performant than Object literals,
       * especially when the JSON file is large.
       *
       * Enabling this disables named imports.
       */
      stringify: false,
    },
    /**
     * ESBuildOptions extends ESbuild's own transform options.
     * The most common use case is customizing JSX.
     *
     * By default, ESBuild is applied to ts, jsx and tsx files.
     * You can customize this with esbuild.include and esbuild.exclude,
     * both of which expects type of string | RegExp | (string | RegExp)[].
     *
     * In addition, you can also use esbuild.jsxInject to automatically inject
     * JSX helper imports for every file transformed by ESBuild:
     */
    esbuild: {
      // jsxFactory: 'h',
      // jsxFragment: 'Fragment',
      // jsxInject: `import React from 'react'`,
    },
    /**
     * Specify additional file types to be treated as static assets so that:
     *
     * - They will be excluded from the plugin transform pipeline when referenced from HTML or directly requested over fetch or XHR.
     * - Importing them from JS will return their resolved URL string (this can be overwritten if you have a enforce: 'pre' plugin to handle the asset type differently).
     */
    // assetsInclude: [],
    /**
     * Adjust console output verbosity. Default is 'info'.
     * Type: 'info' | 'warn' | 'error' | 'silent'
     */
    logLevel: 'info',
    clearScreen: true,
    envDir: 'env',
    host: '0.0.0.0',
    server: {
      strictPort: true,
      https: false,
      /**
       * Type: boolean | string
       * Automatically open the app in the browser on server start. When the value is a string, it will be used as the URL's pathname.
       */
      open: '/',
      cors: true,
      /**
       * File system watcher options to pass on to chokidar.
       */
      watch: {},
    },
    plugins: [
      vue(),
      eslintPlugin({
        formatter: 'eslint-formatter-friendly',
      }),
      legacy({
        targets: ['defaults', 'IE 11'],
      }),
      styleImport({
        libs: [
          {
            libraryName: 'element-plus',
            esModule: true,
            ensureStyleFile: true,
            resolveStyle: (name) => {
              name = name.slice(3)
              return `element-plus/packages/theme-chalk/src/${name}.scss`;
            },
            resolveComponent: (name) => {
              return `element-plus/lib/${name}`;
            },
          }
        ],
      }),
    ]
  }

  if (mode === 'development') {
    defaultConfig.server.proxy = {
      // string shorthand
      '/foo': 'http://localhost:4567/foo',
      // with options
      '/api': {
        target: 'http://jsonplaceholder.typicode.com',
        changeOrigin: true,
        rewrite: (path) => path.replace(/^\/api/, '')
      },
      // with RegEx
      '^/fallback/.*': {
        target: 'http://jsonplaceholder.typicode.com',
        changeOrigin: true,
        rewrite: (path) => path.replace(/^\/fallback/, '')
      },
      // Using the proxy instance
      '/api-proxy': {
        target: 'http://jsonplaceholder.typicode.com',
        changeOrigin: true,
        configure: (proxy, options) => {
          // proxy will be an instance of 'http-proxy'
        },
      }
    }
  }

  return defaultConfig
})
